require 'config/environment'

# CSV形式で書かれた例文の登録
# doc : ファイル名
# rs：区切り文字（オプション）
task :read_example do
  raise "IO Error: Please specify csv file(UTF-8)" unless ENV.has_key? "doc"
  rs = ENV.has_key?("rs") ? ENV["rs"] : "\t"
  require 'MeCab'  
  require 'csv'
  require 'lib/sentence_complexity/Function'
  @complexity_checker = Function.new
  @complexity_checker.crawl("lib/sentence_complexity/bunkei.seed")
  CSV.open(ENV["doc"],"r",rs) do |row|
    next if row.first.include?("-----")
    if /^\d+$/ =~ row.first
      raise "Data Error:emph tag not founded. " unless row[2].include?("<emph>")
      # マーキングされた場所を特定
      parts = row[2].split(/<emph>|<\/emph>/)
      emph_indexes = Array.new
      length = 0
      parts.each_with_index do |part,index|
        emph_indexes << length if (index + 1) % 2 == 0
        length += part.split(//).size
      end
      # 例文を形態素解析し必要な情報を取り出す
      text = parts.join
      data = Array.new
      emph_locations = Array.new
      add_list = Array.new
      base_words = Array.new
      sentence_length = 0
      pos_list = Set.new ["名詞","副詞","形容詞","動詞"]
      length = 0
      i = 0
      MeCab::Tagger.new("-Ochasen").parse(text).split("\n").each_with_index do |line,word_index|
        if /EOS/ !~ line then
          word = line.split("\t")
          surface,reading = word[0..1]
          cur_pos = word[3].split("-")[0]
          length += surface.split(//).size
          sentence_length += 1 unless /^.*記号-.*$/ =~ word[3]
          if i < emph_indexes.size && length > emph_indexes[i]
            emph_locations << word_index
            add_list << word_index
            i += 1
          elsif pos_list.include?(cur_pos)
            add_list << word_index
          end
          data << {"surface" => surface,"reading" => reading}
          base_words << word[2]
        end
      end
      # データを登録
      example = Example.find(:first,:conditions => {:text => text})
      if example.nil?
        complexity = (@complexity_checker.run(text).to_f + 1.0) / 5
        example = Example.create(:text => text,:data => data,:complexity => complexity,:length => sentence_length)
      end
      add_list.each do |text_location|
        if index = emph_locations.index(text_location)
          # 語義情報の取得
          column_index = row[4,@sense_size].index((index + 1).to_s)
          detail = @sense_map[column_index]
        end
        unless detail.nil?
          # 語義情報を持っている単語の登録
          detail.dictionaries.each do |dic|
            Assign.create(:dictionary => dic,:example => example,:text_position => text_location,:sense_position => detail.position)
          end
        else
          # それ以外で検索対象となり得る単語の登録
          keyword = base_words[text_location]
          entries = Dictionary.find(:all,:conditions => {:index => keyword})
          entries << Dictionary.create(:index => keyword,:entry => {"surface" => keyword}) if entries.empty?
          entries.each do |dic|
            Assign.create(:dictionary => dic,:example => example,:text_position => text_location)
          end
        end
      end
    else
      # TIDを手がかりに辞書を検索
      tid = row.last.match("TID=(.+?)\,")[1].to_i
      if row.last.include? "GOGI"
        @sense_size = row.last.match("GOGI=(.+?)=")[1].to_i
      else
        @sense_size = 5
      end
      details = SenseDetail.find(:all,:include => :dictionaries,:conditions => {:tid => tid})
      @sense_map = Hash.new

      row[4,@sense_size].each_with_index do |text,index|
        next if text.blank?
        raise "Data Error:#{index}nd sense matched many senses (TID=#{tid})." if details.select{|detail| detail.text.include? text }.size > 1
        detail = details.find{|detail| detail.text.include? text }
        raise "Data Error:#{index}nd sense not founded (TID=#{tid})." if detail.nil?
        @sense_map[index] = detail
      end
    end
  end
end